import asyncio

from fastapi import FastAPI, WebSocket, WebSocketDisconnect, APIRouter, HTTPException
import json
import logging
from typing import Dict, Any, List
from demo.models.schemas import DeviceInfo, BindRequest, UnbindRequest, DevicePlatformBinding, PlatformInfo
from demo.api.routes import setup_routes
from demo.services.bindings import binding_manager
from demo.services.manager import device_manager
from demo.websocket.manager import ConnectionManager
from demo.websocket.handlers import WebSocketMessageHandler
from demo.services.device_service import DeviceService
from demo.services.ai_service import AIChatService

from openai import OpenAI

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = FastAPI(title="设备管理与AI对话服务")

# 初始化硅基流动客户端
# 关键步骤：配置 base_url 为硅基流动的端点
client = OpenAI(
    api_key="sk-kszqnhnnrdiupkuwkczeeqcqtgqklmubpqeaibiyeguemsti",
    base_url="https://api.siliconflow.cn/v1"  # 硅基流动的 API 端点
)

# 初始化服务
connection_manager = ConnectionManager()
device_service = DeviceService()
ai_service = AIChatService()
message_handler = WebSocketMessageHandler(connection_manager, device_service, ai_service,client)

# 设置API路由
api_router = APIRouter(prefix="/api")
setup_routes(api_router, connection_manager, device_service)
app.include_router(api_router)


@app.websocket("/ws/{device_id}")
async def websocket_endpoint(websocket: WebSocket, device_id: str):
    await connection_manager.connect_device(device_id, websocket)

    try:
        while True:
            # 接收消息
            data = await websocket.receive_text()
            message_dict = json.loads(data)

            # 处理消息
            await message_handler.handle_message(device_id, message_dict, websocket)

    except WebSocketDisconnect:
        connection_manager.disconnect_device(device_id)
    except Exception as e:
        logger.error(f"WebSocket处理错误: {str(e)}")
        connection_manager.disconnect_device(device_id)


# RESTful API 路由
@app.post("/devices/register", response_model=Dict[str, Any])
async def register_device(device_info: DeviceInfo):
    """注册新设备"""
    success = await device_manager.register_device(device_info)
    if success:
        return {"status": "success", "message": "设备注册成功", "device_id": device_info.DeviceId}
    else:
        raise HTTPException(status_code=400, detail="设备注册失败")

@app.get("/devices", response_model=List[DeviceInfo])
async def get_all_devices():
    """获取所有设备信息"""
    return device_manager.get_all_devices()

@app.get("/devices/online", response_model=List[DeviceInfo])
async def get_online_devices():
    """获取在线设备"""
    return device_manager.get_online_devices()

@app.get("/devices/{device_id}", response_model=DeviceInfo)
async def get_device(device_id: str):
    """获取特定设备信息"""
    device = device_manager.get_device_info(device_id)
    if not device:
        raise HTTPException(status_code=404, detail="设备未找到")
    return device

@app.post("/devices/{device_id}/status")
async def update_device_status(device_id: str, is_online: bool, is_used: bool = None):
    """更新设备状态"""
    device_manager.update_device_status(device_id, is_online, is_used)
    return {"status": "success", "message": "设备状态更新成功"}

@app.post("/devices/{device_id}/message")
async def send_message_to_device(device_id: str, message: Dict[str, Any]):
    """向设备发送消息"""
    success = await device_manager.send_to_device(device_id, message)
    if success:
        return {"status": "success", "message": "消息发送成功"}
    else:
        raise HTTPException(status_code=400, detail="消息发送失败")



# RESTful API 路由 - 平台绑定管理
@app.post("/bindings/bind", response_model=Dict[str, Any])
async def bind_device(bind_request: BindRequest):
    """绑定设备到平台"""
    binding = await binding_manager.bind_device_to_platform(bind_request)
    if binding:
        return {
            "status": "success",
            "message": "设备绑定成功",
            "binding_id": binding.binding_id,
            "device_id": binding.device_id,
            "platform_id": binding.platform_id
        }
    else:
        raise HTTPException(status_code=400, detail="设备绑定失败")

@app.post("/bindings/unbind", response_model=Dict[str, Any])
async def unbind_device(unbind_request: UnbindRequest):
    """解绑设备"""
    success = await binding_manager.unbind_specific(
        unbind_request.device_id,
        unbind_request.platform_id,
        unbind_request.reason
    )
    if success:
        return {"status": "success", "message": "设备解绑成功"}
    else:
        raise HTTPException(status_code=400, detail="设备解绑失败")

@app.get("/bindings/device/{device_id}", response_model=DevicePlatformBinding)
async def get_device_binding(device_id: str):
    """获取设备绑定信息"""
    binding = await binding_manager.get_device_binding(device_id)
    if not binding:
        raise HTTPException(status_code=404, detail="未找到设备绑定信息")
    return binding


# 平台管理
@app.get("/platforms", response_model=List[PlatformInfo])
async def get_all_platforms():
    """获取所有平台"""
    return binding_manager.get_all_platforms()

@app.get("/platforms/{platform_id}", response_model=PlatformInfo)
async def get_platform(platform_id: str):
    """获取特定平台信息"""
    platform = binding_manager.get_platform(platform_id)
    if not platform:
        raise HTTPException(status_code=404, detail="平台未找到")
    return platform

@app.post("/platforms", response_model=Dict[str, Any])
async def add_platform(platform: PlatformInfo):
    """添加新平台"""
    success = await binding_manager.add_platform(platform)
    if success:
        return {"status": "success", "message": "平台添加成功"}
    else:
        raise HTTPException(status_code=400, detail="平台添加失败")



# 后台任务 - 定期清理离线设备
@app.on_event("startup")
async def startup_event():
    """启动后台任务"""
    import asyncio
    asyncio.create_task(periodic_cleanup())

async def periodic_cleanup():
    """定期清理任务"""
    while True:
        await asyncio.sleep(300)  # 5分钟
        await device_manager.cleanup_offline_devices()


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8000)